package com.zan.lock;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author Zan
 * @Create 2024/2/29 11:02
 * @Description : 自定义锁
 */
public class LSaleTicket {
    public static void main(String[] args) {
        // 第二步：创建多个线程，调用资源类的操作方法
        LTicket lTicket = new LTicket();

        // 创建三个线程
        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                lTicket.sale();
            }
        }, "AA").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                lTicket.sale();
            }
        }, "BB").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                lTicket.sale();
            }
        }, "CC").start();
    }
}

// 第一步：创建资源类，定义属性和操作方法
class LTicket {
    // 票数
    private int number = 30;

    // 创建可重入锁
    // 非公平锁，可能会导致一个人全部卖完了，但是效率高
    // 公平锁，效率相对要低一点
    private final ReentrantLock lock = new ReentrantLock(false);

    // 卖票的方法
    public void sale() {
        // 上锁
        lock.lock();

        try {
            // 判断是否有票 (注意：如果出现异常，也需要解锁)
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + " : 卖出第" + number-- + "张票, 剩余：" + number);
            }
        } finally {
            // 解锁
            lock.unlock();
        }
    }
}
